Skip to content

Fix remaining #470 console flash: hub server spawn, not just browser-open - #475

Open
richard-devbot wants to merge 2 commits into
mainfrom
fix-472-hub-server-spawn-console-flash
Open

Fix remaining #470 console flash: hub server spawn, not just browser-open#475
richard-devbot wants to merge 2 commits into
mainfrom
fix-472-hub-server-spawn-console-flash

Conversation

@richard-devbot

@richard-devbot richard-devbot commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Problem

The console-window flash from #470 is still happening — #471 fixed the wrong half of it.

Every affected file (auto-launch.js, rstack-sdlc.ts, sandbox.js, dashboard/server.js) makes two spawns:

  1. spawn(cmd, [url], { shell: true }) → opens the browser via cmd.exe /c startthis one got windowsHide in Fix Windows console-window flash on browser/runtime auto-launch #471
  2. spawn(process.execPath, [binPath, ...], { detached: true }) → launches the Business Hub server itself — this one didn't

process.execPath is node.exe, a console-subsystem executable. Spawning it detached: true without windowsHide flashes a console window on win32 regardless of shell — a separate cause from the one #471 fixed. It fires on the path users hit most: Claude Code SessionStartautoLaunchBusinessHub → this spawn, and the equivalent Pi session-start path.

Fix

Added windowsHide: true to the two missed call sites:

  • src/hooks/auto-launch.js — Claude Code hub launch
  • src/integrations/pi/rstack-sdlc.ts — Pi hub launch

autoLaunchBusinessHub now accepts an injectable spawnImpl (same convention as openBrowser/startContainerRuntime) so this is unit-testable without spawning a real process.

Verification

  • New regression test in tests/windows-console-flash-470.test.js, alongside the existing Windows: browser/runtime auto-launch briefly flashes a visible console window #470 coverage — asserts windowsHide: true on the server-launch spawn.
  • tests/windows-console-flash-470.test.js: 7/7 pass.
  • Full suite: 1559 pass / 51 fail — identical 51 failures on an unmodified tree (spawn npx ENOENT, Windows temp-dir EBUSY), the documented pre-existing sandbox limitations. None touch the changed files.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Prevented brief console windows from appearing when launching the Business Hub on Windows.
    • Improved Slack notification formatting across Discord, Microsoft Teams, and text channels.
    • Added support for Slack message fields in both standard and legacy block formats.
    • Corrected Slack message blocks to use the appropriate structure for more reliable rendering.

richardsongunde and others added 2 commits July 27, 2026 12:16
Slack notifications have never been deliverable. Both payload builders in
src/notifications/index.js emitted a block of `{ type: 'fields', fields }`,
but Block Kit has no `fields` block type — fields belong on a `section`
block. Slack rejects the entire attachment with:

    400 invalid_attachments

Verified against a live Incoming Webhook: failing before this change,
delivering successfully after it.

The bogus type had propagated to every consumer, so each one is updated to
read fields off a section block while still tolerating the old shape, which
keeps any in-flight or persisted payloads converting correctly:

  - channels/teams.js   - facts extraction
  - channels/discord.js - embed fields
  - channels/text.js    - plain-text flattening (covered by the existing
                          "slackPayloadToText renders blocks as readable
                          plain text" test, which caught this consumer)

Teams and Discord converters produce identical output to before the change.
tests/notifications-channels.test.js, harness-notifications.test.js and
notify-hook.test.js pass 21/21.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…open

#471 fixed the cmd.exe browser-open spawn (`start <url>` via shell:true) at
four call sites, but each of those files makes a SECOND spawn that #471
missed: launching the Business Hub server itself by spawning node.exe
directly with `detached: true` and no `windowsHide`.

node.exe is a console-subsystem executable. Spawning one detached without
windowsHide flashes a visible console window on win32 independent of the
shell:true/cmd.exe case #471 addressed — so the flash kept happening on
every Claude Code session start (SessionStart hook -> autoLaunchBusinessHub)
and every Pi session start, exactly where users would notice it most.

Fixed the two call sites:
  - src/hooks/auto-launch.js        (Claude Code SessionStart hook)
  - src/integrations/pi/rstack-sdlc.ts (Pi session start)

autoLaunchBusinessHub now accepts an injectable `spawnImpl` (mirroring the
existing openBrowser/startContainerRuntime convention) so the windowsHide
behavior on the server-launch spawn is unit-testable without spawning a
real background process.

Added a regression test to tests/windows-console-flash-470.test.js
alongside the existing #470 coverage. Full suite: 1559 pass / 51 fail, same
51 as an unmodified tree — all spawn ENOENT / temp-dir EBUSY, the
documented pre-existing Windows-sandbox limitations, none touching the
changed files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@strix-security

strix-security Bot commented Jul 27, 2026

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for f080458.


Reviewed by Strix
Re-run review · Configure security review settings

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Business Hub spawn paths now hide detached Windows consoles and support injected spawning for tests. Slack notification formatting now emits standard section field blocks, while converters accept both section and legacy field payloads.

Changes

Business Hub console launch

Layer / File(s) Summary
Hide detached Business Hub consoles
src/hooks/auto-launch.js, src/integrations/pi/rstack-sdlc.ts, tests/windows-console-flash-470.test.js
Business Hub launches set windowsHide: true; the auto-launch path accepts an injectable spawn implementation and has coverage for the detached Windows launch.

Slack field payload handling

Layer / File(s) Summary
Support section-based Slack fields
src/notifications/index.js, src/notifications/channels/*.js
Stage and task messages emit section blocks containing fields, and Discord, Teams, and text conversion accepts fields on section or legacy fields blocks.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: richardsongunde

Poem

A rabbit hops where consoles gleam,
Hidden windows guard the stream.
Slack fields bloom in sections bright,
Old shapes still parse just right.
“Binky!” cheers the Hub tonight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing the remaining Windows console flash in hub server spawning, not just browser-open logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-472-hub-server-spawn-console-flash

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix Win console flash on hub spawn; correct Slack Block Kit fields

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Hide Win32 console flash when launching Business Hub server via detached node.exe spawn
• Make hub auto-launch spawn injectable and add a regression test for windowsHide
• Fix Slack payload blocks (fields → section) and update Teams/Discord/Text converters
Diagram

graph TD
  H["windows-console-flash-470.test.js"] --> A["auto-launch.js"] --> B["spawn(node.exe) windowsHide"] --> C["Business Hub server"]
  H --> D["rstack-sdlc.ts"] --> B
  E["notifications/index.js"] --> F["Slack blocks: section.fields"] --> G["converters: teams/discord/text"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Centralize background process spawning
  • ➕ Prevents missing windowsHide at future detached spawn call sites
  • ➕ Allows consistent defaults (stdio/env/detached) and easier testing
  • ➖ Requires refactoring multiple files and potentially wider blast radius
  • ➖ May be hard to standardize if spawn semantics differ across features
2. Use a GUI-subsystem launcher (nodew.exe) on Windows
  • ➕ Avoids console windows even without windowsHide
  • ➕ Could simplify Windows-specific process behavior
  • ➖ Adds platform-specific branching and distribution complexity
  • ➖ May change debugging/stdio expectations
3. Validate Slack payloads against a Block Kit schema/library
  • ➕ Catches invalid block shapes (like type: 'fields') before sending
  • ➕ Improves long-term safety as payloads evolve
  • ➖ Adds dependency/runtime overhead
  • ➖ May require migration work across notification call sites

Recommendation: The PR’s approach is the right minimal, targeted fix: apply windowsHide to the missed detached node.exe spawns and add a regression test, while correcting Slack Block Kit block types and keeping converters backward-compatible. Consider a follow-up to centralize detached/background spawns to avoid repeating platform-specific flags across the codebase.

Files changed (7) +54 / -7

Bug fix (6) +25 / -6
auto-launch.jsInjectable spawn + windowsHide on hub server spawn +10/-1

Injectable spawn + windowsHide on hub server spawn

• Adds an injectable spawn implementation (spawnImpl) to make hub-launch behavior testable. Updates the detached node.exe spawn to include windowsHide: true to prevent Win32 console flashing.

src/hooks/auto-launch.js

rstack-sdlc.tsHide console flash when Pi launches hub server +5/-0

Hide console flash when Pi launches hub server

• Updates the detached node.exe spawn used to launch the Business Hub server to include windowsHide: true, preventing a console window flash on Windows.

src/integrations/pi/rstack-sdlc.ts

discord.jsRead Slack fields from section blocks (tolerate legacy type) +2/-1

Read Slack fields from section blocks (tolerate legacy type)

• Adjusts Slack-to-Discord conversion to treat fields as belonging to section blocks while still accepting legacy blocks with type: 'fields'. Prevents dropped fields after Slack payload shape correction.

src/notifications/channels/discord.js

teams.jsExtract facts from section.fields (tolerate legacy type) +2/-1

Extract facts from section.fields (tolerate legacy type)

• Updates Teams conversion to read fields from section blocks (the valid Block Kit shape) while tolerating legacy type: 'fields' payloads for backward compatibility.

src/notifications/channels/teams.js

text.jsFlatten section.fields blocks to text (tolerate legacy type) +2/-1

Flatten section.fields blocks to text (tolerate legacy type)

• Updates the plain-text converter to treat fields as part of section blocks, while still accepting legacy type: 'fields' blocks. Maintains readable text output for notifications.

src/notifications/channels/text.js

index.jsFix Slack Block Kit blocks: 'fields' → 'section' +4/-2

Fix Slack Block Kit blocks: 'fields' → 'section'

• Corrects Slack payload builders to emit fields on a section block (Block Kit-compatible) rather than an invalid 'fields' block type. This prevents Slack webhook rejections due to invalid attachments.

src/notifications/index.js

Tests (1) +29 / -1
windows-console-flash-470.test.jsRegression test for windowsHide on hub server spawns +29/-1

Regression test for windowsHide on hub server spawns

• Expands the existing #470 console-flash coverage to include the detached node.exe server-launch spawn. Uses the new spawnImpl injection to assert windowsHide: true without creating a real background process.

tests/windows-console-flash-470.test.js

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/windows-console-flash-470.test.js`:
- Around line 107-114: Make the autoLaunchBusinessHub spawn-branch test
deterministic by stubbing or injecting the isPortOpen check so the configured
port is guaranteed closed, and explicitly set RSTACK_NO_BUSINESS_HUB to enable
launching. Capture and restore the original RSTACK_NO_BUSINESS_HUB value
alongside the existing environment variables, preserving cleanup in all paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a68eea8f-56b8-4342-ac75-d644031ee94a

📥 Commits

Reviewing files that changed from the base of the PR and between cce8808 and f080458.

📒 Files selected for processing (7)
  • src/hooks/auto-launch.js
  • src/integrations/pi/rstack-sdlc.ts
  • src/notifications/channels/discord.js
  • src/notifications/channels/teams.js
  • src/notifications/channels/text.js
  • src/notifications/index.js
  • tests/windows-console-flash-470.test.js

Comment on lines +107 to +114
// A high, effectively-never-bound port so isPortOpen() resolves false and
// the function takes the "spawn a fresh instance" branch under test.
const originalPort = process.env.RSTACK_BUSINESS_PORT;
const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
process.env.RSTACK_BUSINESS_PORT = '58471';
process.env.RSTACK_NO_BROWSER = '1';
try {
await autoLaunchBusinessHub('/tmp/project', { spawnImpl: recordingSpawn(calls) });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Make the spawn branch deterministic.

isPortOpen() checks the real TCP port 58471, so another process can make the test skip the spawn and fail at calls.length === 1. The test also does not override an inherited RSTACK_NO_BUSINESS_HUB=1, which can return before spawning. Inject/stub the port check (or otherwise guarantee a closed port) and explicitly set/restore RSTACK_NO_BUSINESS_HUB.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/windows-console-flash-470.test.js` around lines 107 - 114, Make the
autoLaunchBusinessHub spawn-branch test deterministic by stubbing or injecting
the isPortOpen check so the configured port is guaranteed closed, and explicitly
set RSTACK_NO_BUSINESS_HUB to enable launching. Capture and restore the original
RSTACK_NO_BUSINESS_HUB value alongside the existing environment variables,
preserving cleanup in all paths.

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (4)

Context used
✅ Compliance rules (platform): 300 rules
✅ Skills: 17 invoked
  code-review-pr
  claude-api
  documentation-writing
  pptx
  docx
  performance-monitoring
  security-compliance
  cso
  plan-eng-review
  design-review
  prompt-engineering
  mcp-builder
  qa-testing
  code-patterns
  xlsx
  security-owasp
  testing-qa

Grey Divider


Remediation recommended

1. Duplicated Slack fields parsing 📜 Skill insight ⚙ Maintainability
Description
The PR repeats the same Slack Block Kit fields-handling logic (and explanatory comment) across
multiple notification channel converters, creating a DRY violation and increasing maintenance risk
if the parsing behavior changes again.
Code

src/notifications/channels/discord.js[R24-28]

+      // Fields ride on a section block; 'fields' is tolerated for older payloads.
+      if ((block.type === 'section' || block.type === 'fields') && block.fields) {
        for (const f of block.fields) {
          const raw = f.text || '';
          const parts = raw.split('\n');
Relevance

⭐⭐ Medium

No evidence team enforces DRY in converters; multi-channel code merged as-is (PR #39).

PR-#39

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1399536 requires eliminating duplicated logic. The same `block.type === 'section'
|| block.type === 'fields'` conditional and field-iteration logic was added in three separate
channel converters, indicating copy/paste duplication rather than a shared helper.

src/notifications/channels/discord.js[24-33]
src/notifications/channels/teams.js[27-40]
src/notifications/channels/text.js[26-34]
Skill: plan-eng-review

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Slack `fields` parsing logic is duplicated across multiple notification channel converters, violating DRY and making future schema tweaks easy to miss in one of the implementations.

## Issue Context
The same conditional logic and loop appear in `discord.js`, `teams.js`, and `text.js` to support both the correct Block Kit shape (`section` with `fields`) and a legacy tolerated shape (`type: 'fields'`).

## Fix Focus Areas
- src/notifications/channels/discord.js[24-33]
- src/notifications/channels/teams.js[27-40]
- src/notifications/channels/text.js[26-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. 58471 hardcoded test port 📜 Skill insight ⚙ Maintainability
Description
The test hardcodes the port value 58471 instead of using a named constant. This reduces
readability and makes future updates more error-prone.
Code

tests/windows-console-flash-470.test.js[R109-112]

+  const originalPort = process.env.RSTACK_BUSINESS_PORT;
+  const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
+  process.env.RSTACK_BUSINESS_PORT = '58471';
+  process.env.RSTACK_NO_BROWSER = '1';
Relevance

⭐⭐ Medium

No prior accepted/rejected reviews about replacing magic numbers with named constants in tests.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1400588 requires replacing magic numbers with named constants; the test sets
process.env.RSTACK_BUSINESS_PORT to a literal '58471' without defining a descriptive constant.

tests/windows-console-flash-470.test.js[109-112]
Skill: code-patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A literal port number is used directly in the test (`'58471'`), which violates the magic-number rule.

## Issue Context
This port is intended to be an effectively-unused port to force `isPortOpen()` to return false.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[109-112]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Flaky port-based test 🐞 Bug ☼ Reliability
Description
The new autoLaunchBusinessHub regression test assumes port 58471 is unused so isPortOpen()
returns false; if any process is listening on 127.0.0.1:58471, autoLaunchBusinessHub() will
early-return and never call the injected spawnImpl, causing a nondeterministic test failure.
Code

tests/windows-console-flash-470.test.js[R107-123]

+  // A high, effectively-never-bound port so isPortOpen() resolves false and
+  // the function takes the "spawn a fresh instance" branch under test.
+  const originalPort = process.env.RSTACK_BUSINESS_PORT;
+  const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
+  process.env.RSTACK_BUSINESS_PORT = '58471';
+  process.env.RSTACK_NO_BROWSER = '1';
+  try {
+    await autoLaunchBusinessHub('/tmp/project', { spawnImpl: recordingSpawn(calls) });
+  } finally {
+    if (originalPort === undefined) delete process.env.RSTACK_BUSINESS_PORT; else process.env.RSTACK_BUSINESS_PORT = originalPort;
+    if (originalNoBrowser === undefined) delete process.env.RSTACK_NO_BROWSER; else process.env.RSTACK_NO_BROWSER = originalNoBrowser;
+  }
+  assert.equal(calls.length, 1);
+  assert.equal(calls[0].cmd, process.execPath);
+  assert.equal(calls[0].options.detached, true);
+  assert.equal(calls[0].options.windowsHide, true);
+});
Relevance

⭐⭐ Medium

Flakiness-hardening sometimes rejected (e.g., tmpdir isolation rejected in PR #258); no clear
port-flake precedent.

PR-#258

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The test sets a fixed port and expects exactly one spawnImpl call, but the production
implementation checks whether the port is already accepting TCP connections and returns early if it
is, which bypasses the spawn path entirely.

tests/windows-console-flash-470.test.js[105-123]
src/hooks/auto-launch.js[10-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`tests/windows-console-flash-470.test.js` hard-codes `RSTACK_BUSINESS_PORT=58471` to force `autoLaunchBusinessHub()` down the spawn path. Because `autoLaunchBusinessHub()` performs a real TCP probe (`isPortOpen`) before spawning, a listener on that port will flip the branch and make the test fail intermittently.

### Issue Context
This test is intended to validate `windowsHide: true` on the Business Hub *server-launch* spawn. It should be deterministic and not depend on the machine’s ambient port usage.

### Fix Focus Areas
- src/hooks/auto-launch.js[10-35]
- tests/windows-console-flash-470.test.js[105-123]

### Suggested fix
Add a second injectable dependency to `autoLaunchBusinessHub`, e.g. `opts.isPortOpenImpl ?? isPortOpen`, and use that instead of calling `isPortOpen` directly. In the test, pass `isPortOpenImpl: async () => false` so the spawn path is guaranteed without relying on any specific port.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

4. Regression test lacks attribution metadata 📜 Skill insight ⚙ Maintainability
Description
The updated regression test comment block references #470/#471 but does not include the required
found-date and QA report path metadata. This reduces traceability for why/when the regression
coverage was added and where the original report lives.
Code

tests/windows-console-flash-470.test.js[R9-16]

+ * The original #470/#471 fix covered the browser-open spawn (cmd.exe /c
+ * start) at each call site but missed the OTHER spawn each of those files
+ * makes: launching the Business Hub SERVER itself by spawning node.exe
+ * directly with detached: true. node.exe is a console-subsystem executable,
+ * so that spawn flashes a console too, independent of the shell:true case —
+ * it kept flashing after #471 merged. Covered below for both the Claude
+ * Code hook (auto-launch.js) and the Pi integration (rstack-sdlc.ts).
+ *
Relevance

⭐⭐ Medium

No historical evidence for required regression-test attribution metadata (found-date/QA report
path).

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1400067 requires regression tests to include attribution metadata including the
issue ID, what broke, the date found, and a QA report reference. The updated header comment includes
the issue IDs and description but still lacks a found date and QA report path.

tests/windows-console-flash-470.test.js[1-18]
Skill: qa-testing

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The regression test header comment is missing required attribution metadata (date found and QA report path).

## Issue Context
Compliance requires regression tests to include: issue ID, what broke, date found, and QA report path.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[1-18]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. windows-console-flash-470.test.js regression edit 📜 Skill insight ⚙ Maintainability
Description
A new regression test was added by modifying an existing test file instead of creating a new
dedicated regression test file. This violates the requirement that regression tests be added only as
new files to avoid coupling to existing suites.
Code

tests/windows-console-flash-470.test.js[R105-123]

+test('auto-launch.js autoLaunchBusinessHub: windowsHide:true on the server-launch spawn (missed by #471)', async () => {
+  const calls = [];
+  // A high, effectively-never-bound port so isPortOpen() resolves false and
+  // the function takes the "spawn a fresh instance" branch under test.
+  const originalPort = process.env.RSTACK_BUSINESS_PORT;
+  const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
+  process.env.RSTACK_BUSINESS_PORT = '58471';
+  process.env.RSTACK_NO_BROWSER = '1';
+  try {
+    await autoLaunchBusinessHub('/tmp/project', { spawnImpl: recordingSpawn(calls) });
+  } finally {
+    if (originalPort === undefined) delete process.env.RSTACK_BUSINESS_PORT; else process.env.RSTACK_BUSINESS_PORT = originalPort;
+    if (originalNoBrowser === undefined) delete process.env.RSTACK_NO_BROWSER; else process.env.RSTACK_NO_BROWSER = originalNoBrowser;
+  }
+  assert.equal(calls.length, 1);
+  assert.equal(calls[0].cmd, process.execPath);
+  assert.equal(calls[0].options.detached, true);
+  assert.equal(calls[0].options.windowsHide, true);
+});
Relevance

⭐ Low

Repo commonly extends existing test files; new regression tests added in existing suite (PR #167).

PR-#167

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1400748 requires that adding regression tests be done via new test files only, but
the PR adds a new regression test block inside the existing
tests/windows-console-flash-470.test.js file.

tests/windows-console-flash-470.test.js[105-123]
Skill: qa-testing

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A regression test was added by editing an existing test file, but regression tests must be added as new test files only.

## Issue Context
The PR adds a new regression test for the hub server spawn console-flash case (missed by #471) directly into `tests/windows-console-flash-470.test.js`.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[105-123]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +24 to 28
// Fields ride on a section block; 'fields' is tolerated for older payloads.
if ((block.type === 'section' || block.type === 'fields') && block.fields) {
for (const f of block.fields) {
const raw = f.text || '';
const parts = raw.split('\n');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Duplicated slack fields parsing 📜 Skill insight ⚙ Maintainability

The PR repeats the same Slack Block Kit fields-handling logic (and explanatory comment) across
multiple notification channel converters, creating a DRY violation and increasing maintenance risk
if the parsing behavior changes again.
Agent Prompt
## Issue description
The Slack `fields` parsing logic is duplicated across multiple notification channel converters, violating DRY and making future schema tweaks easy to miss in one of the implementations.

## Issue Context
The same conditional logic and loop appear in `discord.js`, `teams.js`, and `text.js` to support both the correct Block Kit shape (`section` with `fields`) and a legacy tolerated shape (`type: 'fields'`).

## Fix Focus Areas
- src/notifications/channels/discord.js[24-33]
- src/notifications/channels/teams.js[27-40]
- src/notifications/channels/text.js[26-34]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +9 to +16
* The original #470/#471 fix covered the browser-open spawn (cmd.exe /c
* start) at each call site but missed the OTHER spawn each of those files
* makes: launching the Business Hub SERVER itself by spawning node.exe
* directly with detached: true. node.exe is a console-subsystem executable,
* so that spawn flashes a console too, independent of the shell:true case —
* it kept flashing after #471 merged. Covered below for both the Claude
* Code hook (auto-launch.js) and the Pi integration (rstack-sdlc.ts).
*

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

2. Regression test lacks attribution metadata 📜 Skill insight ⚙ Maintainability

The updated regression test comment block references #470/#471 but does not include the required
found-date and QA report path metadata. This reduces traceability for why/when the regression
coverage was added and where the original report lives.
Agent Prompt
## Issue description
The regression test header comment is missing required attribution metadata (date found and QA report path).

## Issue Context
Compliance requires regression tests to include: issue ID, what broke, date found, and QA report path.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[1-18]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +109 to +112
const originalPort = process.env.RSTACK_BUSINESS_PORT;
const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
process.env.RSTACK_BUSINESS_PORT = '58471';
process.env.RSTACK_NO_BROWSER = '1';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

4. 58471 hardcoded test port 📜 Skill insight ⚙ Maintainability

The test hardcodes the port value 58471 instead of using a named constant. This reduces
readability and makes future updates more error-prone.
Agent Prompt
## Issue description
A literal port number is used directly in the test (`'58471'`), which violates the magic-number rule.

## Issue Context
This port is intended to be an effectively-unused port to force `isPortOpen()` to return false.

## Fix Focus Areas
- tests/windows-console-flash-470.test.js[109-112]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +107 to +123
// A high, effectively-never-bound port so isPortOpen() resolves false and
// the function takes the "spawn a fresh instance" branch under test.
const originalPort = process.env.RSTACK_BUSINESS_PORT;
const originalNoBrowser = process.env.RSTACK_NO_BROWSER;
process.env.RSTACK_BUSINESS_PORT = '58471';
process.env.RSTACK_NO_BROWSER = '1';
try {
await autoLaunchBusinessHub('/tmp/project', { spawnImpl: recordingSpawn(calls) });
} finally {
if (originalPort === undefined) delete process.env.RSTACK_BUSINESS_PORT; else process.env.RSTACK_BUSINESS_PORT = originalPort;
if (originalNoBrowser === undefined) delete process.env.RSTACK_NO_BROWSER; else process.env.RSTACK_NO_BROWSER = originalNoBrowser;
}
assert.equal(calls.length, 1);
assert.equal(calls[0].cmd, process.execPath);
assert.equal(calls[0].options.detached, true);
assert.equal(calls[0].options.windowsHide, true);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

5. Flaky port-based test 🐞 Bug ☼ Reliability

The new autoLaunchBusinessHub regression test assumes port 58471 is unused so isPortOpen()
returns false; if any process is listening on 127.0.0.1:58471, autoLaunchBusinessHub() will
early-return and never call the injected spawnImpl, causing a nondeterministic test failure.
Agent Prompt
### Issue description
`tests/windows-console-flash-470.test.js` hard-codes `RSTACK_BUSINESS_PORT=58471` to force `autoLaunchBusinessHub()` down the spawn path. Because `autoLaunchBusinessHub()` performs a real TCP probe (`isPortOpen`) before spawning, a listener on that port will flip the branch and make the test fail intermittently.

### Issue Context
This test is intended to validate `windowsHide: true` on the Business Hub *server-launch* spawn. It should be deterministic and not depend on the machine’s ambient port usage.

### Fix Focus Areas
- src/hooks/auto-launch.js[10-35]
- tests/windows-console-flash-470.test.js[105-123]

### Suggested fix
Add a second injectable dependency to `autoLaunchBusinessHub`, e.g. `opts.isPortOpenImpl ?? isPortOpen`, and use that instead of calling `isPortOpen` directly. In the test, pass `isPortOpenImpl: async () => false` so the spawn path is guaranteed without relying on any specific port.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants